Raw ECG Plots¶

In [1]:
import pandas as pd
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
import plotly.graph_objects as go
from os import listdir

Part 2¶

In [2]:
file = 'Part 2_ECG.csv'
name = file.removesuffix('_ECG.csv')
summary = pd.read_csv(f'{name}_Summary.csv', index_col = 'label')
fs = summary.loc['ECG', 'sample_rate']
unit = summary.loc['ECG', 'dimension']

ecg = pd.read_csv(file)
ecg.insert(0, 'datetime', ecg['timestamp'].apply(lambda x: dt.datetime.fromtimestamp(x / 1000)))
ecg.drop(['timestamp'], axis = 1, inplace = True)
ecg.set_index('datetime', inplace = True)

# Break into 60-second segments
chunk_size = int(fs) * 60
chunks = [ecg.iloc[i:i + chunk_size] for i in range(0, len(ecg), int(chunk_size))]
segments = {}
for c in range(len(chunks)):
    s = c + 1
    segments.update({s: chunks[c]})
Set the segments to be visualized. Note: Each segment is 60 s in duration.
In [3]:
# Set segment numbers
first = 60
last = 66
In [4]:
for i in range(first, last + 1):
    segments[i].plot(linewidth = 0.5, legend = None, figsize = (15, 5))
    plt.title(f'Segment {i} Raw', fontdict = {'fontsize': 16})
    plt.xlabel('Time')
    plt.ylabel(f'{unit}')
    plt.margins(0, 0.05)
    plt.tight_layout()

Part 3¶

Part 3 contains only three (3) segments.
In [5]:
file = 'Part 3_ECG.csv'
name = file.removesuffix('_ECG.csv')
summary = pd.read_csv(f'{name}_Summary.csv', index_col = 'label')
fs = summary.loc['ECG', 'sample_rate']
unit = summary.loc['ECG', 'dimension']

ecg = pd.read_csv(file)
ecg.insert(0, 'datetime', ecg['timestamp'].apply(lambda x: dt.datetime.fromtimestamp(x / 1000)))
ecg.drop(['timestamp'], axis = 1, inplace = True)
ecg.set_index('datetime', inplace = True)

# Break into 60-second segments
chunk_size = int(fs) * 60
chunks = [ecg.iloc[i:i + chunk_size] for i in range(0, len(ecg), int(chunk_size))]
segments = {}
for c in range(len(chunks)):
    s = c + 1
    segments.update({s: chunks[c]})
In [6]:
# Set segment numbers
first = 1
last = 3
In [7]:
for i in range(first, last + 1):
    segments[i].plot(linewidth = 0.5, legend = None, figsize = (15, 5))
    plt.title(f'Segment {i} Raw', fontdict = {'fontsize': 16})
    plt.xlabel('Time')
    plt.ylabel(f'{unit}')
    plt.margins(0, 0.05)
    plt.tight_layout()

ECG QA¶

QA plots are based on output from MindWare's HRV Analyis software.

In [8]:
mws = sorted([f for f in listdir('.') if f.endswith('xlsx') and '~' not in f])
mws
Out[8]:
['Part 2_HRV Analysis_11_55_46 AM.xlsx',
 'Part 3_HRV Analysis_11_58_26 AM.xlsx']
In [9]:
mw = pd.read_excel(mws[0], engine = 'openpyxl', sheet_name = 'Editing Stats', index_col = 0).transpose()
x = mw.index.values
plot = go.Figure(
    data = [go.Bar(name = 'Normal Peaks', x = x, y = mw['Normal Peaks'], marker = dict(color = '#2c63ab'), hovertemplate = '<b>Segment %{x}:</b> %{y} peaks'),
            go.Bar(name = 'Artifact Peaks', x = x, y = mw['Artifact Peaks'], marker = dict(color = '#fcc201'), hovertemplate = '<b>Segment %{x}:</b> %{y} peaks')])
plot.update_layout(
    title = 'Part 2',
    xaxis_title = 'Segment Number',
    yaxis_title = 'Number of R Peaks',
    xaxis = dict(tickmode = 'linear', dtick = 5),
    width = 950,
    height = 500,
    barmode = 'stack', 
    template = 'simple_white')
In [10]:
mw = pd.read_excel(mws[1], engine = 'openpyxl', sheet_name = 'Editing Stats', index_col = 0).transpose()
x = mw.index.values
plot = go.Figure(
    data = [go.Bar(name = 'Normal Peaks', x = x, y = mw['Normal Peaks'], marker = dict(color = '#2c63ab'), hovertemplate = '<b>Segment %{x}:</b> %{y} peaks'),
            go.Bar(name = 'Artifact Peaks', x = x, y = mw['Artifact Peaks'], marker = dict(color = '#fcc201'), hovertemplate = '<b>Segment %{x}:</b> %{y} peaks')])
plot.update_layout(
    title = 'Part 3',
    xaxis_title = 'Segment Number',
    yaxis_title = 'Number of R Peaks',
    xaxis = dict(tickmode = 'linear', dtick = 1),
    width = 950,
    height = 500,
    barmode = 'stack', 
    template = 'simple_white')